import subprocess
import re
import os
from typing import List
from datetime import datetime

def checkFileExist(path:str) ->bool :
    check=os.path.isfile(path)
    return check

def checkDirExist(path:str) -> bool:
    check=os.path.isdir(path)
    return check

def getFilesNameFromDir(DirPath:str)-> List[str]:
    if checkDirExist(DirPath):
        pathDir=os.listdir(DirPath)
        return pathDir
    else:
        print("the DirPath isn't exist")

def getSolVersionFromFile(filePath:str)->str:
    pattern1='(\\^)[\\d]+(\\.[\\d]+)(\\.[\\d]+)'
    pattern2='[\\d]+(\\.[\\d]+)(\\.[\\d]+)'

    with open(filePath,'r',encoding='utf-8') as f:
        content = f.read()

    # content="solidity  0.4.3"
    result1=re.search(pattern1,content)
    if result1!=None:
        solv=result1.group()
        if solv<"^0.5.0":
            solv="0.4.26"
        elif solv<"^0.6.0":
            solv="0.5.17"
        elif solv<"^0.7.0":
            solv="0.6.12"
        elif solv<"^0.8.0":
            solv="0.7.6"
        elif solv<"^0.9.0":
            solv="0.8.4"
        else:
            solv="None"
    else:
        result2=re.search(pattern2,content)
        if result2!=None:
            solv=result2.group()

    return solv

def useMythrilDectectSol(mythPath:str,filePath:str,solv:str,outputPath:str):
    '''
    use mythril to detect .sol file from filePath and output result to outputPath
    '''
    if solv!="None":
        command="myth analyze "+filePath+" --solv"+" "+solv+" --execution-timeout 180 -t2"
        print("command is ",command)
    else:
        command="myth analyze "+filePath+" --execution-timeout  180 -t2"

    child1=subprocess.Popen(command,shell=True,stdout=subprocess.PIPE)
    output,outerr=child1.communicate()
    if outerr!=None:
        print(outerr)
    outputstr=output.decode("utf-8")
    # if the sol is safe ,don't output
    if outputstr!="The analysis was completed successfully. No issues were detected.\n\n":
        fileName=filePath.split("/")[-1]
        with open(outputPath+"/"+fileName,"a") as f:
            f.write(outputstr)
            print("PC have detected %s and output the result"%filePath)
    else:
        print("PC have detected %s,it has no issues"%filePath)
    
    child1.kill()



def useMythrilDetectFileInDir(mythPath:str,DirPath:str,outputPath:str):
    files=getFilesNameFromDir(DirPath)
    for file in files:
        filePath=DirPath+"/"+file
        solv=getSolVersionFromFile(filePath)
        try:
            print("#########################################################")
            print("PC is processing %s"%filePath)
            # print(solv)
            useMythrilDectectSol(mythPath,filePath,solv,outputPath)
        except Exception as e:
            print("%s doesn't run,err is %s"%(filePath,e))
            continue

def getallDir(dirPath:str) -> List[str]:
    res=[]
    for root,dirs,files in os.walk(dirPath):
        for d in dirs:
            print(os.path.join(root,d))
        for file in files:
                #获取文件所属目录
            # print(root)
                #获取文件路径
            # print(os.path.join(root,file))
            res.append(os.path.join(root,file))    
    
    for r in res:
        print(r)
    return [dirPath]


 
def mkdir(path):
 
	folder = os.path.exists(path)
 
	if not folder:                   #判断是否存在文件夹如果不存在则创建为文件夹
		os.makedirs(path)            #makedirs 创建文件时如果路径不存在会创建这个路径
		# print("---  new folder...  ---")
		# print("---  OK  ---")
 
	else:
		print("---  mkdir filed, The folder has existed  ---")
		


def startMythril(solFilePath: str,outputFilePath: str):
    for root,dirs,files in os.walk(solFilePath):
        for dir in dirs:
            inputFilePath=os.path.join(root,dir)
            outFilePath=os.path.join(outputFilePath,dir)
            mkdir(outFilePath)
            try:
                useMythrilDetectFileInDir("mythPath",inputFilePath,outFilePath)
                print(inputFilePath,outFilePath)
            except Exception as e:
                print("%s doesn't run,err is %s"%(inputFilePath,e))
                continue
            # useMythrilDetectFileInDir(mythPath,solDir,outputDir)

def delete_null_dir(dirr):
    
    files=os.listdir(dirr)
    # print(dirr)
    for file in files:
        d=os.path.join(dirr,file)
        print(d)
        if not os.listdir(d):
            print(d)
            os.rmdir(d)



solFilePath="/home/hello/Desktop/ERC721/ERC721_2-56/contracts"
outputFilePath="/home/hello/Desktop/ERC721/ERC721_2-56/Result"

# print(getSolVersionFromFile("/home/hello/Desktop/TestMythril/contracts/3_BNB/# BNB.sol"))
startMythril(solFilePath,outputFilePath)
delete_null_dir(outputFilePath)
# print(getallDir("D:/hello/hello world"))s



# starttime=datetime.now()
# print(starttime)
# mythPath="/home/hello/Desktop/mythril-develop/myth"
# solDir="/home/hello/Desktop/L"
# outputDir="/home/hello/Desktop/LResult"
# useMythrilDetectFileInDir(mythPath,solDir,outputDir)
# endtime=datetime.now()
# print(endtime)
# print("RunTime: {}h-{}m-{}s".format(endtime.hour-starttime.hour, endtime.minute-starttime.minute, endtime.second-starttime.second))


